#include "messageshowarea.h"
#include"userinfowidget.h"
#include"model/datacenter.h"

MessageShowArea::MessageShowArea(QWidget *parent)
    :QScrollArea(parent)
{
    // 1. 初始化基础属性
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    this->setMinimumHeight(450);
    // ⼀定要添加这个设置, 否则⽆法正确显⽰.
    this->setWidgetResizable(true);

    //给QScrollArea和其垂直滚动条安装事件过滤器
    this->viewport()->installEventFilter(this);
    this->verticalScrollBar()->installEventFilter(this);

    //设置滚动条样式
    this->setStyleSheet(R"(
        QScrollArea { border: none;border-bottom: 1px solid #D5D5D5; border-left: 1px solid #D5D5D5;}

        QScrollBar:vertical {
            border: none;
            background: transparent;  /* 设置固定的背景颜色 */
            width: 10px;          /* 设置固定宽度 */
            margin: 0px;
        }

        QScrollBar::handle:vertical {
            background: transparent;
            height: 50px;
            min-height: 50px;
            max-height: 50px;
            border-radius: 5px;
        }

        QScrollBar::add-line:vertical,
        QScrollBar::sub-line:vertical {
            height: 0px;          /* 隐藏上下箭头 */
        }

        QScrollBar::add-page:vertical,
        QScrollBar::sub-page:vertical {
            background: transparent;
        }
        QScrollBar:horizontal {height: 0px;}

    )");

    container = new QWidget();
    this->setWidget(container);

    QVBoxLayout* layout = new QVBoxLayout();
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    container->setLayout(layout);


}

void MessageShowArea::addMessage(bool isLeft, const model::Message &message)
{
    MessageItem* messageItem = MessageItem::makeMessageItem(isLeft, message);
    container->layout()->addWidget(messageItem);
}

void MessageShowArea::addFrontMessage(bool isLeft, const model::Message &message)
{
    MessageItem* messageItem = MessageItem::makeMessageItem(isLeft, message);
    QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(container->layout());
    layout->insertWidget(0, messageItem);
}

void MessageShowArea::clear()
{
    QLayout* layout = container->layout();
    // 从后往前遍历. 否则删除前⾯的元素会影响后⾯元素的下标
    for (int i = layout->count() - 1; i >= 0; i--) {
        QLayoutItem* item = layout->takeAt(i);
        if (item->widget()) {
            delete item->widget();
        }
        delete item;
    }

}

void MessageShowArea::scrollToEndLater()
{
    LOG() << "scrollToEndLater";
    QTimer* timer = new QTimer();
    connect(timer, &QTimer::timeout, this, [=]() {
        // 执⾏滚动操作
        int maxValue = this->verticalScrollBar()->maximum();
        this->verticalScrollBar()->setValue(maxValue);
        // 销毁定时器
        timer->stop();
        timer->deleteLater();
    });
    timer->start(500);
}

bool MessageShowArea::eventFilter(QObject *watched, QEvent *event)
{
    //当鼠标进入到该区域或滚动条区域时，显示滑块，否则隐藏
    if (watched == this->viewport()|| watched == this->verticalScrollBar()){
        {
            switch (event->type()) {
            case QEvent::Enter:
                // 鼠标进入Viewport或滚动条区域
                //设置滚动条样式
            this->verticalScrollBar()->setStyleSheet(R"(
                QScrollBar:vertical {
                    border: none;
                    background: transparent;  /* 设置固定的背景颜色 */
                    width: 10px;          /* 设置固定宽度 */
                    margin: 0px;
                }

                QScrollBar::handle:vertical {
                    background: #c0c0c0;
                    height: 50px;
                    min-height: 50px;
                    max-height: 50px;
                    border-radius: 5px;
                }

                QScrollBar::add-line:vertical,
                QScrollBar::sub-line:vertical {
                    height: 0px;          /* 隐藏上下箭头 */
                }

                QScrollBar::add-page:vertical,
                QScrollBar::sub-page:vertical {
                    background: transparent;
                }
                QScrollBar:horizontal {height: 0px;}

             )");
                break;
            case QEvent::Leave:
                // 鼠标离开Viewport或滚动条区域
                this->verticalScrollBar()->setStyleSheet(R"(
                QScrollBar:vertical {
                    border: none;
                    background: transparent;  /* 设置固定的背景颜色 */
                    width: 10px;          /* 设置固定宽度 */
                    margin: 0px;
                }

                QScrollBar::handle:vertical {
                    background: transparent;
                    height: 50px;
                    min-height: 50px;
                    max-height: 50px;
                    border-radius: 5px;
                }

                QScrollBar::add-line:vertical,
                QScrollBar::sub-line:vertical {
                    height: 0px;          /* 隐藏上下箭头 */
                }

                QScrollBar::add-page:vertical,
                QScrollBar::sub-page:vertical {
                    background: transparent;
                }
                QScrollBar:horizontal {height: 0px;}

             )");
                break;
            default:
                break;
            }
        }
    }

    return QObject::eventFilter(watched, event); // 调用基类的事件过滤器
}

MessageItem::MessageItem(bool isLeft)
    :isLeft(isLeft)
{

}

MessageItem *MessageItem::makeMessageItem(bool isLeft, const model::Message &message)
{
    // 1. 创建基本⻣架
    MessageItem* messageItem = new MessageItem(isLeft);
    QGridLayout* layout = new QGridLayout();
    layout->setContentsMargins(40, 10, 40, 0);
    layout->setHorizontalSpacing(10);
    layout->setVerticalSpacing(10);
    // layout->setColumnStretch(0, 0);
    // layout->setColumnStretch(1, 10);
    messageItem->setMinimumHeight(100);
    messageItem->setLayout(layout);

    // 2. 创建头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40, 40);
    avatarBtn->setIconSize(QSize(40, 40));
    avatarBtn->setIcon(message.sender.avatar);
    if (isLeft) {
        layout->addWidget(avatarBtn, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignLeft);
    } else {
        layout->addWidget(avatarBtn, 0, 1, 2, 1, Qt::AlignTop | Qt::AlignLeft);
    }

    // 3. 创建名字 和 时间
    QLabel* nameLabel = new QLabel();
    nameLabel->setText(message.sender.nickname + " | " + message.time);
    nameLabel->setAlignment(Qt::AlignBottom);
    nameLabel->setStyleSheet("QLabel { font-size: 12px; color: rgb(178, 178,178); }");
    if (isLeft) {
        layout->addWidget(nameLabel, 0, 1);
    } else {
        layout->addWidget(nameLabel, 0, 0, Qt::AlignRight);
    }

    // 4. 创建消息体
    QWidget* contentWidget = nullptr;
    switch (message.messageType) {
    case model::TEXT_TYPE:
        contentWidget = makeTextMessageItem(message.content, isLeft);
        break;
    case model::IMAGE_TYPE:
        contentWidget = makeImageMessageItem(message.fileId, message.content,isLeft);
        break;
    case model::FILE_TYPE:
        contentWidget = makeFileMessageItem(message.fileId, message.content,isLeft, message.fileName);
        break;
    case model::SPEECH_TYPE:
        contentWidget = makeSoundMessageItem(message.fileId, message.content,isLeft);
        break;
    default:
        LOG() << "error messageType! messageType = " << message.messageType;
    }
    if (isLeft) {
        layout->addWidget(contentWidget, 1, 1);
    } else {
        layout->addWidget(contentWidget, 1, 0);
    }

    // 5. 关联信号槽
    // 5.1 点击头像, 弹出窗⼝显⽰⽤⼾信息.
    connect(avatarBtn, &QPushButton::clicked, messageItem, [=]() {
        UserInfoWidget* userInfoWidget = new UserInfoWidget(message);
        userInfoWidget->show();
        LOG() << "头像信息";
    });
    // 5.2 ⽤⼾修改了昵称, 则修改昵称内容.
    if(!isLeft){
        model::DataCenter* dataCenter = model::DataCenter::getInstance();

        connect(dataCenter, &model::DataCenter::changeNickNameDone, messageItem, [=](){
            nameLabel->setText(dataCenter->getMyselfInfo()->nickname + " | " + message.time);
        });

        // 调整头像
        connect(dataCenter, &model::DataCenter::changeAvatarDone, messageItem, [=]() {
            avatarBtn->setIcon(dataCenter->getMyselfInfo()->avatar);
        });
    }
    return messageItem;
}

QWidget *MessageItem::makeTextMessageItem(const QByteArray &content, bool isLeft)
{
    // ⽂本消息不需要 fileId
    MessageContentLabel* item = new MessageContentLabel(model::TEXT_TYPE, QString(content), "", content, isLeft);
    return item;
}

QWidget *MessageItem::makeImageMessageItem(const QString &fileId, const QByteArray &content, bool isLeft)
{
    MessageImageLabel* item = new MessageImageLabel(fileId, content, isLeft);
    return item;
}

QWidget *MessageItem::makeFileMessageItem(const QString &fileId, const QByteArray &content, bool isLeft, const QString &fileName)
{
    MessageContentLabel* item = new MessageContentLabel(model::FILE_TYPE, "[⽂件] " +fileName, fileId, content, isLeft);
    return item;
}

QWidget *MessageItem::makeSoundMessageItem(const QString &fileId, const QByteArray &content, bool isLeft)
{
    MessageContentLabel* item = new MessageContentLabel(model::SPEECH_TYPE, "[语⾳]",fileId, content, isLeft);
    return item;
}



MessageContentLabel::MessageContentLabel(model::MessageType type, const QString &text, const QString &fileId, const QByteArray &content, bool isLeft)
    :messageType(type), fileId(fileId), content(content), isLeft(isLeft)
{
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    QFont font;
    font.setFamily("微软雅⿊");
    font.setPixelSize(16);

    this->label = new QLabel(this);
    this->label->setText(text);
    this->label->setFont(font);
    this->label->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
    this->label->setWordWrap(true);
    this->label->setStyleSheet("QLabel { padding: 0 10px; line-height: 1.2; background-color: transparent;}");
}

void MessageContentLabel::paintEvent(QPaintEvent *)
{
    // 1. 拿到⽗元素的宽度
    QObject* object = this->parent();
    if (!object->isWidgetType()) {
        return;
    }

    QWidget* parent = dynamic_cast<QWidget*>(object);
    // 宽度设置为⽗元素的 60%
    int width = parent->width() * 0.6;

    // 2. 计算⽂本的⾏数, 进⼀步得到⾼度
    QFontMetrics metrics(this->label->font());
    // 显⽰这些⽂本⼀共需要多宽
    int totalWidth = metrics.horizontalAdvance(this->label->text());
    int rows = (totalWidth / (width - 40)) + 1; // - 40 是给左右两侧留下⾜够的空隙
    if (totalWidth + 40 < width) {
        // ⽂本只有⼀⾏, 且不⾜⼀⾏, 就直接调整成更⼩的宽度
        width = totalWidth + 40;
    }
    // + 20 是给上下留下点空⽩控件, 1.2 是考虑到⾏间距的问题
    int height = rows * (this->label->font().pixelSize() * 1.2) + 20;

    // 4. 绘制圆⻆矩形
    QPainter painter(this);
    // 设置抗锯⻮
    painter.setRenderHint(QPainter::Antialiasing);
    // 在这⾥画个⼩箭头 + 矩形
    QPainterPath path;
    if(isLeft){
        //设置画笔和画刷为白色
        painter.setPen(QPen(QColor(255, 255, 255), 1));
        painter.setBrush(QColor(255, 255, 255));


        path.addRoundedRect(10, 0, width, height, 10, 10);
        path.moveTo(10, 15);
        path.lineTo(0, 20);
        path.lineTo(10, 25);
        path.closeSubpath();

        painter.drawPath(path);

        // 5. 把 QLabel 移动到合适的位置
        this->label->setGeometry(10, 0, width, height);
    }
    else{
        painter.setPen(QPen(QColor(137, 217, 97), 1));
        painter.setBrush(QColor(137, 217, 97));

        // x 轴的起始位置. 此处⽤⾃⾝的 宽度 减去 label 的宽度, 再往左挪 10px
        int leftPos = this->width() - width - 10;
        int rightPos = this->width() - 10;
        path.addRoundedRect(leftPos, 0, width, height, 10, 10);
        path.moveTo(rightPos, 15);
        path.lineTo(rightPos + 10, 20);
        path.lineTo(rightPos, 25);
        path.closeSubpath();

        painter.drawPath(path);

        // 5. 把 QLabel 移动到合适的位置
        this->label->setGeometry(leftPos, 0, width, height);

    }

    // 6. 设置⽗元素的⾼度, 确保⽗元素能够把当前整个⽂本都显⽰完整.
    // 50 这个数字是拍脑⻔拍的. 根据实际情况微调
    parent->setFixedHeight(height + 50);
}

MessageImageLabel::MessageImageLabel(const QString &fileId, const QByteArray &content, bool isLeft)
    :fileId(fileId), content(content), isLeft(isLeft)
{

}
